package com.freedom.rpc.thrift.common.zookeeper.client;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import com.freedom.rpc.thrift.common.extended.ServiceNameFieldHelper;
import com.freedom.rpc.thrift.common.extended.TFramedTransportFieldHelper;
import com.freedom.rpc.thrift.common.extended.TServiceClientFieldHelper;
import com.freedom.rpc.thrift.common.utils.Logger;
import com.freedom.rpc.thrift.common.utils.TimeUtils;

public class ClientSideZkReadyListener {
	private static final Logger logger = Logger.getLogger(ClientSideZkReadyListener.class);
	private static Thread zkThread = null;
	private static Thread zkConsumerThread = null;
	static {
		// 启动就判断是否可以创建字段反射，否则没必要启动了...
		try {
			Class.forName(ServiceNameFieldHelper.class.getName());
		} catch (ClassNotFoundException e) {
			logger.error("no class ServiceNameFieldHelper found..." + e);
			System.exit(-1);
		}
		try {
			Class.forName(TFramedTransportFieldHelper.class.getName());
		} catch (ClassNotFoundException e) {
			logger.error("no class TransportFieldHelper found..." + e);
			System.exit(-1);
		}
		try {
			Class.forName(TServiceClientFieldHelper.class.getName());
		} catch (ClassNotFoundException e) {
			logger.error("no class TransportFieldHelper found..." + e);
			System.exit(-1);
		}
		// 启动时，就注册ZK相关线程
		zkThread = new Thread(new ClientSideZkThread());
		zkThread.setDaemon(true);
		zkThread.setName("Client: ZooKeeper  Register Thread...");
		zkThread.start();
		// 启动时，启动event的消费者线程
		zkConsumerThread = new Thread(new ClientSideZkEventConsumer());
		zkConsumerThread.setDaemon(true);
		zkConsumerThread.setName("Consumer for Zk event...");
		zkConsumerThread.start();
		//
		logger.info("client zookeeper register thread start...");
	}

	//
	private static volatile AtomicBoolean zkReady = new AtomicBoolean(false);

	public static void countdown() {
		zkReady.set(true);
	}

	public static void ready() {
		// 必须用这种方式，否则在有的地方，比如发现tomcat中使用client的jar包会报异常
		while (false == zkReady.get()) {
			logger.info("waiting for zk to be ready...");
			TimeUtils.sleep(1000);
		}
	}
}
